package br.com.itc.componentes.util.servico
{
	
	import br.com.itc.componentes.Alerta;
	import br.com.itc.componentes.MostraCursor;
	
	import mx.collections.ArrayCollection;
	import mx.core.Application;
	import mx.managers.CursorManager;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.InvokeEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.mxml.RemoteObject;

	/**
	 * Serviço padrão a ser usado pelas aplicações JAVA.
	 */	
	public class ServicoJava extends RemoteObject {

//************
// Constantes:
//************

		public const MENSAGEM_PADRAO:String = "Erro ao se realizar a operação.";
		public const DESTINATION_JAVA_PADRAO:String = "servicosJava";
		
//***********
// Atributos:
//***********

		private var _mensagemErro:String = MENSAGEM_PADRAO;

		private var _bloquearOperacao:Boolean = false;
		private var _mensagemEspera:String = "Realizando a Operação...";
		private var _cursorOcupado:int = MostraCursor.CURSOR_PESQUISAR;
		private var _tratamentoErroPadrao:Boolean = true;

		private var _funcoesResultado:ArrayCollection = new ArrayCollection();

//**************
// Construtores:
//**************

		public function ServicoJava(destination:String = null) {
			super(destination);

			super.addEventListener(InvokeEvent.INVOKE, operacaoChamada);
			super.addEventListener(FaultEvent.FAULT, erroOcorrido);
			super.addEventListener(ResultEvent.RESULT, resultadoRetornado);

			showBusyCursor = true;
		}

//**********************
// Métodos Sobrescritos:
//**********************

		public override function set destination(destino:String):void {
			super.destination =
					(destino != null && destino.length > 0) 
					? destino : DESTINATION_JAVA_PADRAO;
		}

	    public override function addEventListener(type:String, 
		    	listener:Function, useCapture:Boolean = false, priority:int = 0, 
		    	useWeakReference:Boolean = false):void {
			if (type == ResultEvent.RESULT) {
				_funcoesResultado.addItem(listener);
			}  else {
				super.addEventListener(type, listener, useCapture, priority, 
						useWeakReference);
			}
	    }

//*********
// Eventos:
//*********

		protected function operacaoChamada(evento:InvokeEvent):void {
			if (_bloquearOperacao) {
				MostraCursor.setBusyCursor(_mensagemEspera, 
						Application.application, _cursorOcupado);
			}
		}

		protected function resultadoRetornado(evento:ResultEvent):void {
			MostraCursor.removeBusyCursor();
			CursorManager.removeBusyCursor();

			for each (var _funcaoResultado:Function in _funcoesResultado) {
				_funcaoResultado(evento);
			}
		}

		protected function erroOcorridoCursor(evt:FaultEvent = null):void {
			MostraCursor.removeBusyCursor();
			CursorManager.removeBusyCursor();
		}

		protected function erroOcorrido(evt:FaultEvent):void {
			var msg:String = mensagemErro;

			erroOcorridoCursor(evt);

			if (evt.fault != null && evt.fault.faultString != null) {
				msg = recuperarMensagem(evt.fault);
				
				if (msg == 'error' || msg == 'warn') {
					msg = mensagemErro;
				}
			}

			Alerta.show(msg, "Erro!", Alerta.TIPO_ALERTA);
		}

//********************
// Métodos Auxiliares:
//********************

		protected function recuperarMensagem(fault:Object):String {
			return fault.faultString;
		}

//*******************
// Getters e Setters:
//*******************

		public function set mensagemErro(value:String):void {
            _mensagemErro = value;
        }
        public function get mensagemErro():String {
            return _mensagemErro;
        }

		public function set bloquearOperacao(value:Boolean):void {
            _bloquearOperacao = value;
        }
        public function get bloquearOperacao():Boolean {
            return _bloquearOperacao;
        }

        public function set mensagemEspera(value:String):void {
            _mensagemEspera = value;
        }
        public function get mensagemEspera():String {
            return _mensagemEspera;
        }

        public function set cursorOcupado(value:int):void {
            _cursorOcupado = value;
        }
        public function get cursorOcupado():int {
            return _cursorOcupado;
        }
        
        public function set tratamentoErroPadrao(value:Boolean):void {
        	_tratamentoErroPadrao = value;

        	if (!_tratamentoErroPadrao) {
        		super.removeEventListener(FaultEvent.FAULT, erroOcorrido);
        		super.addEventListener(FaultEvent.FAULT, erroOcorridoCursor);
        	} 
        }
        public function get tratamentoErroPadrao():Boolean {
            return _tratamentoErroPadrao;
        }

	}
}